﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Imagine;
using Box2D.XNA;
using Microsoft.Xna.Framework;

namespace Carmack
{
    public class GameCameraManager
    {
        int nextValue;
        Random m_rand;
        eCameraEffect   m_effect;
        Vector2         m_direction;
        Vector2         m_shakeLimit;
        float           m_limitingFactor;
        int             m_stepSize;
        Stack<int>      m_intStack;
        bool            m_recoil;
        static GameCameraManager m_instance;

        public GameCameraManager()
        {
            m_rand = new Random();
            m_effect = eCameraEffect.NoEffect;
            m_limitingFactor = 0.0f;
            m_stepSize = 0;
            m_recoil = false;
        }

        protected void SmallShake()
        {
           m_direction = -1 * GameManager.Instance().MyHero.Direction;  // Returns Normalized Vector
           m_limitingFactor = 0.35f;
           m_shakeLimit = (m_limitingFactor * m_direction) + m_direction;
           m_recoil = true;
           m_stepSize = 0;
        }

        public bool SetEffect(eCameraEffect effect)
        {
            if (m_effect == eCameraEffect.NoEffect)
            {
                m_effect = effect;
            }
            else
            {
                return false;
            }

            switch (m_effect)
            {
                case eCameraEffect.SmallShake: SmallShake();  break;
                case eCameraEffect.MediumShake: break;
                case eCameraEffect.LargeShake: break;
            }

            return true;
        }

        public void Update()
        {
            if (m_effect == eCameraEffect.SmallShake) 
            { 
                if ( m_stepSize >= 0 && m_recoil == true )
                {
//                    m_recoil = true;
                    m_stepSize += 1;
                }
                if ( m_stepSize > 1  && m_recoil == true )
                { 
                    m_recoil = false;
                    m_direction *= -1;
                }
                else if (m_stepSize > 0 && m_recoil == false)
                {
                    m_stepSize -= 1;
                }
                else if (m_stepSize <= 0 && m_recoil == false)
                {
                    m_effect = eCameraEffect.NoEffect;
                    return;
                }
                
                
                Vector3 CamPos = Engine.Instance().Camera.Position;
                Vector2 AddPos = new Vector2( 0.3f, 0.3f );
                
                nextValue = m_rand.Next(0, 5);
                float x = (float)Math.Cos( (double)nextValue*0.2);
                float y = (float)Math.Asin(0.1*2.0*nextValue);

                float randomAngle = m_rand.Next( 0, 60 ); // (pi/180) rad = 1*
                randomAngle *=   3.141592f/180.0f;

                
               // y = ( m_direction.Y  * (float)Math.Cos((float) randomAngle) );
               // x = ( m_direction.X  * (float)Math.Atan((float) randomAngle) );

                switch( nextValue )
                {
                case 1: AddPos = new Vector2( 0.7f, 0.9f );  break;
                case 2: AddPos = new Vector2( 0.6f, 0.7f );  break;
                case 3: AddPos = new Vector2( 0.8f, 0.5f );  break;
                case 14: break;
                default: AddPos = new Vector2( x, y );  break;
                }
                AddPos = (AddPos * m_direction);
                CamPos.X += AddPos.X;
                CamPos.Y += AddPos.Y;
                Engine.Instance().Camera.Position = CamPos;
            }
        }

        public Matrix GetTransformation()
        {
            return Engine.Instance().Camera.GetTransformation();
        }

        public Camera Camera
        {
            get { return Engine.Instance().Camera;  }
            set { Engine.Instance().Camera = value; }
        }
    }
}